#include "dht11.h"

//PG9
void DHT11_Init(void)
{
	//GPIO结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//使能GPIOG组时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //9号引脚、10号引脚
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; 
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽输出
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //带上拉电阻
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHz
	
	//初始化结构体
	GPIO_Init(GPIOG,&GPIO_InitStruct);

}

void DHT11_Mode(GPIOMode_TypeDef Mode)
{
	//GPIO结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//使能GPIOG组时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //9号引脚、10号引脚
  GPIO_InitStruct.GPIO_Mode = Mode; 
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽输出
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //带上拉电阻
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHz
	
	//初始化结构体
	GPIO_Init(GPIOG,&GPIO_InitStruct);

}

unsigned int time = 0;

//启动处理
int DHT11_Start(void)
{
  DHT11_Init();
	DHT11_Mode(GPIO_Mode_OUT);
	
	DQ_OUT = 1;
	delay_us(10);
	
	//启始信号
	DQ_OUT = 0;
	delay_ms(20);
	
	DQ_OUT = 1;
	delay_us(30);

	DHT11_Mode(GPIO_Mode_IN);
	
	//等待响应信号
	time = 0;
	while(DQ_IN==1) //判断是否接收到响应信号
	{
	  delay_us(1);
		
		time++;
		
		if(time>=200)
			return -1;
	}
	//while(DQ_IN==0);
	//此时，从机电平信号为低
	
	time = 0;
	while(DQ_IN==0) //判断从机是否发送响应信号的低电平信号
	{
	  delay_us(1);
		
		time++;
		
		if(time>=200)
			return -2;
	}
	//while(DQ_IN==1);
	//此时，从机电平信号为高
	
	time = 0;
	while(DQ_IN==1)  //判断从机是否发送响应信号的低电平信号
	{
	  delay_us(1);
		
		time++;
		
		if(time>=200)
			return -3;
	}
	//while(DQ_IN==0);
	//此时，从机电平信号为低
	
	return 0;

}

u_char DHT11_Read_Byte(void)
{
	 u_char data = 0; //data = 0b 0000 0000; 
	 int i=0;
	
   for(i=0;i<8;i++)
	 {
	   	time = 0;
		  while(DQ_IN==0) //判断是否开始传输数据 -- 过滤准备数据信号（低电平信号）
			{
				delay_us(1);
				
				time++;
				
				if(time>=200)
					return 1;
			}
			//此时为高电平信号 -- 数值信号
			
			delay_us(50);
			
			if(DQ_IN==1)//判断此时电平是否依然为高，为高则表示数值“1”
			{
			  data |= 1<<(7-i); //小端序 -- 高位地址先保存数据值
				
			  time = 0;
				while(DQ_IN==1) //判断是否依然
				{
					delay_us(1);
					
					time++;
					
					if(time>=200)
						return 2;
				}

			}
	
	   
	}
  
	return data;
}

int DHT11_Read(u_char *data)
{
	  int i=0;
	
		for(i=0;i<5;i++)
	  {
		  data[i] = DHT11_Read_Byte();
		
		}
		
		if(data[4] == data[0]+data[1]+data[2]+data[3])
			return 0;
		
		return -1;


}



